<?php
/**
 * 公共控制器
 */

namespace app\common\controller;
use think\Controller;
use think\Auth;

class AdminBase extends Controller {
    protected $data = [];
    protected $error_info = '';
    protected $mod = '';
    protected $jumpUrl = '';
    protected $assignList = [];//配置
    protected $searchConfigData = [];
    protected $msgText = [];//站内信
	public function __construct() {
		//获取返回的类型  默认html
		$param = IS_GET ? $_GET : $_POST;
		$param && $this->data = $param;
		$_GET = $_POST = $this->data;
		$GLOBALS['format'] = IS_AJAX ? 'json' :'html';
        $this->_setDefaultConfig();//设置默认的配置
		$this->_initialize();
	}
    protected function _initialize() {
        //判断用户是否被锁定
        if(true !== $this->userLocks()){
            $this->error($this->error_info,$this->jumpUrl);
        }
        //判断登录是否已经过期
        if(true !== $this->userActive()){
            $this->error($this->error_info,$this->jumpUrl);
        }
        //权限检测
        if(true !== $this->chechAuth()){
            $this->error($this->error_info,$this->jumpUrl);
        }
    }
    public function error($msg = '',$url = ''){
        $data = [
            'message' => $msg,
            'jumpurl' => $url,
            'status'  => 0,
        ];
        $url = MODULE_NAME.'/'.CONTROLLER_NAME.'/'.ACTION_NAME;
        $resType = in_array($url,['admin/index/index']) ? 'html' : 'json';
        if($resType === 'json'){
            exit(json_encode($data));
        }else{
            header('location:'.U('admin/Login/login'));
            exit;
        }
    }
    //判断上次操作时间是不是在允许范围内（30分钟）
    protected function userActive()
    {
        $user_active = session('user_active');
        if($user_active)
        {
            if (NOW_TIME-$user_active > 1800)
            {
                session('user_active',null);
                session('username',null);
                session('aid',null);
                session('is_admin',null);
                $this->error_info = '登陆已过期,请重新登陆';
                $this->jumpUrl = U('admin/Login/login');
                return false;
            }else
            {
                session('user_active',NOW_TIME);
                return true;
            }
        }else
        {
            session('user_active',null);
            session('username',null);
            session('aid',null);
            session('is_admin',null);
            $this->error_info = '登陆已过期,请重新登陆';
            $this->jumpUrl = U('admin/Login/login');
            return false;
        }
    }
    //判断用户是否被锁定
    protected function userLocks()
    {
        $aid = decrypt_id(session('aid'));
        $activeUser = M('admin')->where(array('id'=>$aid))->find();
        if($activeUser['lock'] != 1)
        {
            $this->error_info = '用户被锁定！';
            $this->jumpUrl = U('admin/Login/login');
            return false;
        }else
        {
            return true;
        }
    }
    protected function chechAuth(){
        //session不存在时，不允许直接访问
        $aid = decrypt_id(session('aid'));
        if(!$aid || !session('username')){
            $this->error_info = '还没有登录，正在跳转到登录页';
            $this->jumpUrl = U('admin/Login/login');
            return false;
        }

        $not_check = array(
            'admin/login/login',        //登录
            'admin/login/check',        //登录验证
            'admin/index/index',        //后台首页
            'admin/index/info',         //样式表
            'admin/user/account',       //找号设置
            'admin/login/loginout',     //退出登录
            'admin/index/iconfont',     //网站图标
            'admin/msgtext/index',      //站内信
            'admin/msgtext/readmsg',    //阅读站内信
            'admin/msgtext/delmsg',      //删除站内信
            'admin/msgtext/delsendmsg',      //删除站内信
            'admin/msgtext/msgnum',      //JS轮询未读站内信条数
        );
        //白名单列表
        if(in_array(strtolower(MODULE_NAME.'/'.CONTROLLER_NAME.'/'.ACTION_NAME), $not_check)){
            return true;
        }
        //超级管理员绕过验证
        $aid = decrypt_id(session('aid'));
        if(in_array($aid,C('ADMINISTRATOR')))
        {
            return true;
        }
        //下面代码动态判断权限
        $auth = new \think\Auth();
        if(!$auth->check(strtolower(MODULE_NAME.'/'.CONTROLLER_NAME.'/'.ACTION_NAME),decrypt_id(session('aid')),$type=1,$mode='url',$relation='and')){
            $this->error_info = '没有权限';
            $this->jumpUrl = 'self';
            return false;
        }
        return true;
    }
	public function __get($name) {
		return $this->data[$name];
	}
	public function __set($name, $value) {
		$this->data[$name] = $value;
	}
	protected function getError() {
		return $this->error_info;
	}
    protected function _setDefaultConfig(){
        $this->assignList = [
            'initAdminMenu' => false,
        ];
    }
	/**
	 * @name 检测请求的数据
	 * @access protected
	 * @param array $must 必须的参数
	 * @param string $method 请求方式  默认不限制
	 * @return boolean 
	 */
	protected function checkData($must = [], $method = '') {
		if ($method) {
			$method = (strtolower($method) == 'get') ? (IS_GET ? true : false):(IS_POST ? true : false);
			if (!$method) {
				$this->error_info = '请求方式不正确';
				return false;
			}
		}
        
		if (!empty($must)) {
            foreach($must as $v){
                if(!$this->$v){
                    $this->error_info = '请填写完整';
				    return false;
                }
            }
		}
		return true;

	}
    /**
     * @name 加载模板和页面输出 可以返回输出内容
     * @access public
     * @param string $template 模板文件名
     * @param array  $vars     模板输出变量
     * @param string $cache_id 模板缓存标识
     * @return mixed
     */
    public function fetch($template = '', $vars = [], $cache_id = '')
    {
        //传递默认值
        $this->assignDefault();
        return parent::fetch($template, $vars, $cache_id);
    }
    protected function assignDefault(){
        $this->assign('pageTitle',$this->pageTitle);
        $this->assign('pageKeyword',$this->pageKeyword);
        $this->assign('pageAuthor',$this->pageAuthor);
        $this->assign('searchConfig',$this->searchConfigData);
        $this->msgText();
        $this->assign('msgText',$this->msgText);
        foreach($this->assignList as $k=>$v){
            if($v === true){
                $fun = '_'.$k;
                if(is_callable([$this,$fun])){
                    call_user_func([$this,$fun]);
                }
            }
        }
    }
    /**
     * @name 初始化导航菜单
     */
    protected function _initAdminMenu(){

        $menu = zb_read_file('menu');
        //根据用户权限展示可以操作的菜单
        $menu = multi_array_sort($menu,'sort',SORT_ASC);
        //超级管理员拥有所有菜单列表
        if(!in_array(decrypt_id(session('aid')),C('ADMINISTRATOR')))
        {
            $menu = $this->getAuthMenu($menu,'menus');
        }
        $this->assign('admin_menu',$menu);

    }
    /**
     * @name 检测输入的验证码是否正确，$code为用户输入的验证码字符串
     */
    public function check_verify($code, $id = ''){
        $verify = new \org\Verify();
        return $verify->check($code, $id);
    }
    public function _empty(){
        if(IS_AJAX){
            return ['status'=>0,'message'=>'操作失败'];
        }
        return $this->error('请先登陆','',U('admin/Login/login'));
    }
    	/**
	 * @name 调用服务发送请求操作
	 * @param string $type 请求的类型   [post,put,get,delete]
	 * @param array $params 请求时携带的参数
	 * @param string $url  请求的url
	 * @return array 请求后的返回数据
	 */
	protected function request($type = '', $params = [], $url = '',$hasError = false) {
		if (!$type || !$url) {
			return [];
		}
		//加载httpful
		vendor('Bootstrap', VENDOR_PATH . 'Httpful' . DS);
		//初始化
		\Httpful\Bootstrap::init();
		//参数拼接
		if (in_array($type, ['get', 'delete'])) {
			$url .= '?' . http_build_query($params);
			$send = \Httpful\Request::$type($url);
		} else {
			$send = \Httpful\Request::$type($url)
				->sendsForm()
				->body($params);
		}
        if(is_array($this->header) && $this->header){
    		foreach ($this->header as $key => $val) {
    		    if(!$key || !$val) continue;
    			$send = $send->$key($val);
    		}
        }
		$response = $send
			->expectsHtml()
			->send();
		//数据转换为数组返回
        //数据转换为数组返回
        if($hasError){
            return ['hasError' => $response->hasErrors()];
        }
		return object2array($response->body);
	}
    /**
     * @name 查找指定字符串,指定次数,出现的位置
     * @param string $str 原始字符串
     * @param string $find 需要查找的字符串
     * @param int $n 出现的次数
     * @return int 位置
     */
    public function str_n_pos($str = '',$find = '',$n = 1){
        for ($i=1;$i<=$n;$i++){
            $pos = strpos($str,$find);
            $str = substr($str,$pos + 1);
            $pos_val = $pos + $pos_val + 1;
        }
        return $pos_val - 1;
    }
    public function getAuthMenu(array $menuList,string $key)
    {
        $auth = new \think\Auth();
        $re = [];
        if(is_array($menuList) && !empty($menuList))
        {
            $aid = decrypt_id(session('aid'));
            foreach($menuList as $k => $v)
            {
                //判断有没有链接
                if($v['href'])
                {
                    //检测权限
                    $href = strtolower($v['href']);
                    if(preg_match('/^\/?\w+.php[\/\?]?/i',$href,$matchs))
                    {
                        //如果是以.php开头的,获取.php之后的字符串
                        $href = str_replace($matchs[0],'',strstr($href,$matchs[0]));
                        //如果替换之后为空,表示是单独的入口文件,或Index/index/index,允许访问
                        if(!$href){
                            $re[$k] = $v;
                        }else{
                            $href = mb_substr($href,0,$this->str_n_pos($href,'/',3));
                            $auth->check($href,$aid,1,'url','and') && $re[$k] = $v;
                        }
                    }elseif(preg_match('/^(\/\w+){2}\/\w+/i',$href)){
                        //使用U方法生成的标准链接
                        $href = mb_substr(strchr($href,'.',true),1);
                        $auth->check($href,$aid,1,'url','and') && $re[$k] = $v;
                    }else{
                        //其他,包含JavaScript,完整的url,或者非U方法的链接
                        $re[$k] = $v;
                    }
                }
                if(is_array($v[$key])){
                    $v[$key] = $this->getAuthMenu($v[$key],$key);
                    if(!empty($v[$key])){
                        $re[$k] = $v;
                    }
                }
                
            }
        }
        return array_filter($re);
    }
    /**
     * @name 通用搜索功能配置
     */
    public function searchConfig(array $searchConfig){
        $this->searchConfigData = $searchConfig;
    }
    /**
     * @name 站内信提示
     */
    public function msgText(){
        $recMsg = M('admin_message')->where(array('rec_id'=>decrypt_id(session('aid')),'state'=>array('lt',3)))->order('create_time desc')->find();
        $recMsg['msgText'] = M('admin_msg_text')->where(array('id'=>$recMsg['msg_id']))->find();
        $this->msgText['title'] = $recMsg['msgText']['title'];
        $this->msgText['id'] = $recMsg['msgText']['id'];
    }
}
